package org.ala.tiktools.rpc.plugin.load_balance.nacos;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.ala.tiktools.logs.LoggerFactory;
import org.ala.tiktools.rpc.plugin.load_balance.AbstractDynamicLoadBalance;
import org.ala.tiktools.rpc.plugin.node.NodeKey;
import org.slf4j.Logger;
import org.springframework.context.ApplicationContext;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;

/**
 * @author ala
 * @date 2025-04-10 23:04
 */
public class NacosLoadBalance extends AbstractDynamicLoadBalance {


    static Logger log = LoggerFactory.getLogger("rpc", "loadBalance");


    public static final String NACOS_SERVER_ADDRESS = "spring.cloud.nacos.discovery.server-addr",
                                NACOS_SERVER_GROUP = "spring.cloud.nacos.discovery.group",
                                NACOS_SERVER_NAMESPACE = "spring.cloud.nacos.discovery.namespace";
    protected NamingService namingService;
    protected String group, namespace;

    @Override
    protected void init(ApplicationContext context) {
        try {
            String serverAddr = env.getProperty(NACOS_SERVER_ADDRESS, String.class);
            if (serverAddr == null) {
                throw new NacosException(-1, String.format("[NacosLoadBalance init] 无法解析nacos地址 key:%s", NACOS_SERVER_ADDRESS));
            }
            group = env.getProperty(NACOS_SERVER_GROUP, String.class, "DEFAULT_GROUP");
            namespace = env.getProperty(NACOS_SERVER_NAMESPACE, String.class, "public");
            namingService = NacosFactory.createNamingService(serverAddr);
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected Set<NodeKey> loadNodeKeyFromRemote(String serviceName) {
        List<Instance> ins;
        try {
            ins = namingService.selectInstances(serviceName, group, true);
        } catch (NacosException e) {
            log.error("[NacosLoadBalance loadNodeKeyFromRemote] 无法解析nacos地址 key:{}", serviceName);
            return null;
        }

        Set<NodeKey> res = new HashSet<>();
        for (Instance in : ins) {
            String host = in.getIp();
            String sport = in.getMetadata().get(AbstractDynamicLoadBalance.METADATA_PORT);
            try {
            	int[] ports = parsePorts(sport);
            	for (int port : ports) {
            		res.add(NodeKey.build(host, port));
            	}
            } catch (Exception e) {
                log.error("[NacosLoadBalance loadNodeKeyFromRemote] 解析节点信息失败 host:{}, port:{}", host, sport, e);
            }
        }
        return res;
    }
}
